﻿using System;
using System.Collections.Generic;
using System.Linq;
using Com.Framework.Util.Cache;

namespace Com.Azure.Common.Util.Cache
{
    /// <summary>
    /// Azure Redis缓存: StackExchange.Redis
    /// </summary>
    public class RedisCacheService : ICache
    {
        private int _databaseCount = 5;
        private int _databaseStartId = 11;//Redis Database Id range: 11~15
        public int DatabaseId
        {
            get
            {
                if (_databaseStartId != 0)
                    return _databaseStartId;
                return 0;
            }
            set
            {
                _databaseCount = 0;
                _databaseStartId = value;//DatabaseId如果设置了就不随机分配,SharedCacheUtil设置了DatabaseId=10,跟cfwin项目共享10
            }
        }

        public T GetCache<T>(string key)
        {
            //LogUtil.LogInfo("--------RedisCacheService GetCache:" + key);

            return new RedisHelper(GetDatabaseId(key)).StringGet<T>(key);
        }

        public object GetCache(Type type, string key)
        {
            //LogUtil.LogInfo("--------RedisCacheService GetCache:" + key);

            return new RedisHelper(GetDatabaseId(key)).StringGet(type, key);
        }

        public void SetCache<T>(string key, T obj)
        {
            new RedisHelper(GetDatabaseId(key)).StringSet(key, obj);
        }

        public void SetCache<T>(string key, T obj, TimeSpan slidingExpiration)
        {
            new RedisHelper(GetDatabaseId(key)).StringSet(key, obj, slidingExpiration);
        }

        public void SetCache<T>(string key, T obj, DateTime absoluteExpiration)
        {
            var slidingExpiration = absoluteExpiration.Subtract(DateTime.UtcNow);
            new RedisHelper(GetDatabaseId(key)).StringSet(key, obj, slidingExpiration);
        }

        public void RemoveCache(string key)
        {
            new RedisHelper(GetDatabaseId(key)).KeyDelete(key);
        }

        public void RemoveAllCache()
        {
            for (var i = _databaseStartId; i < _databaseStartId + _databaseCount; i++)
                new RedisHelper(i).RemoveAllCache();
        }

        public List<string> GetCacheKeyList(string key = null)
        {
            var result = new List<string>();
            for (var i = _databaseStartId; i < _databaseStartId + _databaseCount; i++)
                result.AddRange(new RedisHelper(i).GetAllKeys(key).ToList());

            return result;
        }

        public bool ExistKey(string key)
        {
            return new RedisHelper(GetDatabaseId(key)).KeyExists(key);
        }

        public int GetDatabaseId(string key)
        {
            if (_databaseCount == 0)
                return _databaseStartId;
            return Math.Abs((key.GetHashCode() % _databaseCount)) + _databaseStartId;
        }
    }
}
